//
//  ViewController.m
//  blockTestOfBlog
//
//  Created by Song on 2018/5/8.
//  Copyright © 2018年 Song. All rights reserved.
//

#import "ViewController.h"
#import "TestCycleRetain.h"
#import "NSObject+Calculate.h"

typedef void (^sayhello)();
typedef NSUInteger (^unintger)(NSUInteger b);
typedef void (^myblockTypedef)();

@interface ViewController ()

@end

@implementation ViewController

    int global_a = 1;
    static int global_b = 2;

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // block捕获外部变量
//    [self blockCatchOut];
    
    // block循环引用
//    [self cycleRetain];
    
    // block链式编程
//    [self lianshi];
    
    // block函数式编程
    [self hanshu];
}

// block捕获外部变量
-(void)blockCatchOut {
    NSLog(@"===========================返回值和参数都为int=================================");
    int (^returnint)(int) = ^int (int i) {
        NSLog(@" === %zd === ",i);
        return i+1;
    };
    int a = returnint(2);
    NSLog(@"%zd",a);
    
    NSLog(@"=========================typedef简化 == 无返回值无参数列表=================================");
    sayhello hello = ^() {
        NSLog(@"hello ----- ");
    };
    hello();
    
    NSLog(@"=========================typedef简化 == NSUInteger===================================");
    unintger unintint = ^(NSUInteger b) {
        NSLog(@" === %zd === ",b);
        return b+2;
    };
    NSUInteger aa = unintint(33);
    NSLog(@"%zd",aa);
    
    NSLog(@"=========================捕获全局变量和静态全局变量===================================");
    void (^blockname)(void) = ^void (void) {
        global_a ++;
        global_b ++;
        NSLog(@"在Block中：global_a = %d, global_b = %d", global_a, global_b);
    };
    global_a++;
    global_b++;
    NSLog(@"在Block外1：global_a = %d, global_b = %d", global_a, global_b);
    blockname();
    NSLog(@"在Block外2：global_a = %d, global_b = %d", global_a, global_b);
    
    NSLog(@"==============================捕获静态变量，局部变量========================================");
    static int static_a = 1;
    int part_a = 1;
    __block int part_b = 1;
    void (^myblock)(void) = ^ {
        static_a ++;
        part_b ++;
        NSLog(@"内部：static_a = %d, part_a = %d, part_b = %d",static_a,part_a,part_b);
    };
    static_a++;
    NSLog(@"外部1：static_a = %d",static_a);
    myblock();
    NSLog(@"外部2：static_a = %d, part_b = %d",static_a,part_b);
}

// block循环引用
-(void)cycleRetain {
    NSLog(@"============================== block循环引用 ========================================");
    TestCycleRetain *obj = [[TestCycleRetain alloc] init];
    obj = nil;
}

// block链式编程
-(void)lianshi {
    /*
     要实现链式调用的一个关键点：就是每次调用add方法必须返回自身，然后才可以继续调用，如此一致循环下去，实现这一切都是Block的功劳
     */
    int result = [NSObject makeCalculate:^(CalculateManager *mgr) {
        mgr.add(5).add(6).add(7).add(8);
        mgr.add(2);
    }];
    NSLog(@"%zd",result);
}

// block函数式编程
-(void)hanshu {
    CalculateManager *mgr = [[CalculateManager alloc] init];
    [[[[mgr calculate:^int(int result) {
        result += 5;
        result *= 5;
        return result;
    }] printResult:^(int result2) {
        NSLog(@"第一次计算结果：%zd",result2);
    }] calculate:^int(int result3) {
        result3 -= 3;
        result3 /= 2;
        return result3;
    }] printResult:^(int result4) {
        NSLog(@"第二次计算结果：%zd",result4);
    }];
}
@end
